package com.study.jyg.rxjava2study.activity;

import android.annotation.SuppressLint;
import android.graphics.Color;
import android.os.Handler;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;

import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.SimpleItemAnimator;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;

import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.viewholder.BaseViewHolder;
import com.github.mikephil.charting.charts.BarChart;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.BarData;
import com.github.mikephil.charting.data.BarDataSet;
import com.github.mikephil.charting.data.BarEntry;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.highlight.Highlight;
import com.github.mikephil.charting.listener.ChartTouchListener;
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
import com.study.jyg.rxjava2study.R;
import com.study.jyg.rxjava2study.base.BasicActivity;
import com.study.jyg.rxjava2study.utils.AdapterInit;
import com.study.jyg.rxjava2study.utils.DensityUtil;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

public class LineChartActivity2 extends BasicActivity implements OnChartValueSelectedListener {

    private BarChart barChart;
    private LineChart chart;
    private Button btnCL;
    private final String CONTENT = "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 60 32 17 3D 48 EC 38 3E 2D 43 28 B8 24 6E 3C 03 24 45 2E 17 28 5D 25 31 39 37 23 09 30 D6 35 D8 25 DF 15 19 33 C1 1F B0 04 A8 42 08 0E B6 29 78 25 F9 32 FD 81 4B 42 12 8A 4C 5D 32 92 BD 8F DA 65 A5 8F D0 60 1D DB 50 A5 1F D7 66 EB 67 A4 9A 0A B0 93 BC 0A A3 B4 EA CD 8A E9 1B 97 DD 03 12 80 8F FB F6 A5 6A BF 85 D9 3E 88 CA EA EF 5C 68 DC EE 75 E8 AF 37 AD 5E 72 63 C5 AD 2A D9 CE 02 64 29 A3 98 9B 58 59 44 AD 38 04 64 B6 C0 41 67 9C 3A 81 BC 63 17 B8 3D 1E 8A B4 93 3B D9 A4 6B 8F 43 62 13 CD 67 24 41 BD F8 60 9D 66 46 78 87 15 DD 7A 8C 21 AF 5E 9D 22 FC 3B 16 26 93 16 AE 51 D3 2A D9 4B 5A 44 9A 4D 26 76 9E 2A 45 55 99 5D 10 44 3A 4C FA 43 B9 52 DD 67 15 2E 13 57 F6 3C E7 62 03 4C A4 31 52 58 EF 0C C0 54 58 2E 0F 34 2E 3B 5E 0E 03 3F 9D 0D D5 36 5C 27 3C 2C 77 3D 37 10 38 4C 3F 12 BD 42 5E 33 02 26 A0 42 12 04 D4 3D B8 1E 78 2B 38 2F 4C 0E 7C 29 95 0F 3C 18 1D 1A 9E 0D DA 1A 8D 09 73 13 3D 0E 3A 08 FB 0C E6 06 73 0A 25 0A 28 07 B6 0C CD 09 F3 09 E7 0D B7 08 06 0E 5E 0C DF 07 BA 0F 7B 02 E2 0B AF 09 4D 05 66 0B 9E 04 8D 09 C5 06 26 09 5C 06 23 09 F2 07 8D 05 F5 0B 95 01 46 0C F9 05 C7 09 55 0C 88 04 78 0F 7C 05 6E 10 39 0F 26 0B D5 13 93 0C 06 13 67 12 33 11 75 15 63 0F CC 15 7B 13 29 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00";
    private int position;
    private boolean startCL;
    private ArrayList<BarEntry> values;
    private float CHART_HEIGHT;
    private float chartHeight;
    private final float AXIS_Y = 300f;
    private float axisY;

    private List<Integer> secondData;
    private Handler mHandler = new Handler();
    private Runnable runnable;
    private BaseQuickAdapter<ZZData, BaseViewHolder> adapter;
    private float scrollY;
    private int dataSize;
    private int dataPositione;
    private StaggeredGridLayoutManager manager;

    @Override
    protected int getLayout() {
        return R.layout.activity_line_chart2;
    }

    @Override
    protected void initView() {
        initChart();
        initBarChart();
        btnCL = findViewById(R.id.btnCL);
        btnCL.setOnClickListener(v -> {
            if (startCL) {
                startCL = false;
                btnCL.setText("测量");
            } else {
                startCL = true;
                btnCL.setText("停止");
            }
        });
        initAdapter();
    }

    private void initAdapter(){
        RecyclerView recyclerView = findViewById(R.id.recyclerView);
        ((SimpleItemAnimator)recyclerView.getItemAnimator()).setSupportsChangeAnimations(false);
        manager = new StaggeredGridLayoutManager(1, StaggeredGridLayoutManager.HORIZONTAL);
        adapter = AdapterInit.initRecyclerView(recyclerView, R.layout.item_view_chart, manager, R.color.colorWhite, 0, (helper, item) -> {
            helper.setText(R.id.tvBottom, String.valueOf(item.getPsotion()));

            View viewZz = helper.getView(R.id.viewZz);
            LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) viewZz.getLayoutParams();
            if (item.isHasData()){
                params.height = DensityUtil.dip2px(item.getHeight());
            }else {
                params.height = 0;
            }
            params.rightMargin = DensityUtil.dip2px((float) item.getSpacing()/2);
            params.leftMargin = DensityUtil.dip2px((float)item.getSpacing()/2);
            viewZz.setLayoutParams(params);
        });
        recyclerView.post(()->{
            int width = recyclerView.getWidth();
            dataSize = width/DensityUtil.sp2px(25)+1;
            List<ZZData> list = new ArrayList<>();
            for (int i = 0; i < dataSize; i++) {
                list.add(new ZZData(i, "", 40,10,false));
            }
            adapter.setNewData(list);
        });
    }

    static class ZZData{
        private int psotion;
        private boolean hasData;
        private String name;
        private int height;
        private int spacing;

        public ZZData(int psotion, String name, int height, int spacing, boolean hasData) {
            this.psotion = psotion;
            this.name = name;
            this.height = height;
            this.spacing = spacing;
            this.hasData = hasData;
        }

        public int getPsotion() {
            return psotion;
        }

        public void setPsotion(int psotion) {
            this.psotion = psotion;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getHeight() {
            return height;
        }

        public void setHeight(int height) {
            this.height = height;
        }

        public int getSpacing() {
            return spacing;
        }

        public void setSpacing(int spacing) {
            this.spacing = spacing;
        }

        public boolean isHasData() {
            return hasData;
        }

        public void setHasData(boolean hasData) {
            this.hasData = hasData;
        }
    }

    @SuppressLint("ClickableViewAccessibility")
    private void initChart() {
        axisY = AXIS_Y;
        chart = findViewById(R.id.chart1);
        chart.post(() -> {
            chartHeight = CHART_HEIGHT = chart.getHeight();
            Log.e("initChart", "height = " + chartHeight + ", HEIGHT = " + CHART_HEIGHT);
        });
        // 背景色
        chart.setBackgroundColor(Color.WHITE);
        // 图表的文本描述
        chart.getDescription().setEnabled(false);
        // 手势设置
        chart.setTouchEnabled(true);
        // 添加监听器
        chart.setOnChartValueSelectedListener(this);
        chart.setDrawGridBackground(false);

        // 自定义 MarkView，当数据被选择时会展示
//        MyMarkerView mv = new MyMarkerView(this, R.layout.custom_marker_view);
//        mv.setChartView(chart);
//        chart.setMarker(mv);

        // 设置拖拽、缩放等
        chart.setDragEnabled(true);
        chart.setScaleEnabled(true);
        chart.setScaleXEnabled(false);
        chart.setScaleYEnabled(true);
        chart.setOnTouchListener((v, event) -> {
            if (v.getId() == R.id.chart1){
                v.getParent().requestDisallowInterceptTouchEvent(true);
                if (event.getAction() == MotionEvent.ACTION_UP) {
                    v.getParent().requestDisallowInterceptTouchEvent(false);
                }
            }
                return false;
        });
//        chart.setOnTouchListener(new ChartTouchListener(chart) {
//            @Override
//            public boolean onTouch(View v, MotionEvent event) {
//                switch (event.getAction()) {
//                    case MotionEvent.ACTION_DOWN:
//                        eventIndexs.add(event.getActionIndex());
//                        scrollY = event.getY();
//                        Log.e("onTouch", "ACTION_DOWN");
//                        break;
//                    case MotionEvent.ACTION_MOVE:
//                        if (eventIndexs.size()>0){
//
//                        }
//                        ViewGroup.LayoutParams params = chart.getLayoutParams();
//                        float y = event.getY() - scrollY;
//                        if (chartHeight <= CHART_HEIGHT && y < 0) {
//                            params.height = (int) CHART_HEIGHT;
//                            chart.setLayoutParams(params);
//                            chart.getAxisLeft().resetAxisMaximum();
//                            chart.getAxisLeft().setAxisMaximum(AXIS_Y);
//                            break;
//                        }
//                        chart.getAxisLeft().resetAxisMaximum();
//                        axisY = axisY + (y / CHART_HEIGHT) * AXIS_Y;
//                        chart.getAxisLeft().setAxisMaximum((int) axisY);
//                        chartHeight = chartHeight + y;
//                        params.height = (int) chartHeight;
//                        chart.setLayoutParams(params);
//                        scrollY = event.getY();
//                        Log.e("onTouch", "ACTION_MOVE:" + y);
//                        break;
//                    case MotionEvent.ACTION_UP:
//                        Log.e("onTouch", "ACTION_UP");
//                        break;
//                    case MotionEvent.ACTION_CANCEL:
//                        Log.e("onTouch", "ACTION_CANCEL");
//                        break;
//                }
//                return true;
//            }
//        });

        // 设置双指缩放(setScaleEnabled(false)参数为false时这个设置已经失效了)
//        chart.setPinchZoom(true);

        setX();
        setY();
        initRunnable();
//        setData();
//        chart.getViewPortHandler().setZoom(20f, 0f);
//        chart.zoom( 30f/*60*30*4f*/, 0f, 0f,0f);
//        chart.zoom(1f, 0f, 0f, 0f, YAxis.AxisDependency.LEFT);
//        chart.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
//            @Override
//            public void onGlobalLayout() {
////                chart.zoomAndCenterAnimated(20f, 0f, 20f, 0f, YAxis.AxisDependency.LEFT, 3000);
//            }
//        });
//        chart.setOnChartGestureListener();
    }

    private void initRunnable() {
        runnable = () -> {
            chart.clearAnimation();
            chart.animateX(1000);
            chart.clear();
            setData();
            if (startCL) {
                int data = 0;
                for (int i = 0; i < secondData.size(); i++) {
                    if (data < secondData.get(i)) {
                        data = secondData.get(i);
                    }
                }
                if (dataPositione == adapter.getItemCount()){
//                    adapter.addData( new ZZData(dataPositione, "", 40, 10, true));
                    adapter.getData().add(new ZZData(dataPositione, "", 40, 10, true));
                    adapter.notifyDataSetChanged();
//                    adapter.addData(new ZZData(dataPositione, "", 40, 10, true));
                }else {
                    adapter.setData(dataPositione, new ZZData(dataPositione, "", 40, 10, true));
                }
                manager.scrollToPosition(dataPositione);
//                manager.scrollToPosition(adapter.getItemCount()-1);
                dataPositione++;
                addBarData(data);
            }
            mHandler.postDelayed(runnable, 1000);
        };
        mHandler.post(runnable);
    }


    private void setX() {
        // 获取 X 轴
        XAxis xAxis = chart.getXAxis();
        xAxis.setAxisMaximum(1024);
        // 允许显示 X 轴的垂直网格线
        xAxis.enableGridDashedLine(10f, 0f, 2f);
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
    }

    private void setY() {
        // 获取 Y 轴
        YAxis yAxis = chart.getAxisLeft();
        // 禁止右轴
        chart.getAxisRight().setEnabled(false);
        // Y 轴的水平网格线
        yAxis.enableGridDashedLine(10f, 0f, 2f);
        // 设置 Y 轴的数值范围
        yAxis.setAxisMaximum(AXIS_Y);
        yAxis.setAxisMinimum(0f);
    }

    private void setData() {
        if (secondData == null)
            secondData = new ArrayList<>();
        secondData.clear();
        Log.e("LineChart", "setData");
        // 1. 每个数据是一个 Entry
        ArrayList<Entry> values = new ArrayList<>();
        String[] contents = CONTENT.split(" ");
        for (int i = 0; i < contents.length /*60*30*/; i++) {
            Random random = new Random();
//            int shuju = random.nextInt(300);
            int shuju = covert(contents[i % contents.length]);
            shuju = shuju == 0 ? shuju : random.nextInt(shuju);
            Log.e("linechart", "shuju = " + shuju);
            secondData.add(shuju);
            values.add(new Entry(i * (2), shuju, /*getResources().getDrawable(R.mipmap.ic_launcher_round)*/ null));
        }
        // 2. 创建一个数据集 DataSet ，用来添加 Entry。一个图中可以包含多个数据集
        LineDataSet set1 = new LineDataSet(values, "DataSet 1");
//        set1.setFillFormatter(new IFillFormatter() {
//            @Override
//            public float getFillLinePosition(ILineDataSet iLineDataSet, LineDataProvider lineDataProvider) {
//
//                return 1000;
//            }
//        });
        // 3. 通过数据集设置数据的样式，如字体颜色、线型、线型颜色、填充色、线宽等属性
        // draw dashed line
        set1.enableDashedLine(10f, 0f, 2f);
        // black lines and points
        set1.setColor(Color.BLUE);
        set1.setCircleColor(Color.BLUE);
        // line thickness and point size 设置折线和顶点得绘制宽度
        set1.setLineWidth(0.51f);
//        set1.setCircleRadius(0.5f);
        set1.setDrawCircles(false);
        // draw points as solid circles
        set1.setDrawCircleHole(false);
        // 4.将数据集添加到数据 ChartData 中
        LineData data = new LineData();
        data.addDataSet(set1);
        // 5. 将数据添加到图表中
        chart.setData(data);
    }

    @Override
    public void onValueSelected(Entry entry, Highlight highlight) {
        Log.e("LineChartActivity2", "onValueSelected");
    }

    @Override
    public void onNothingSelected() {
        Log.e("LineChartActivity2", "onNothingSelected");
    }


    /**
     * @param: [content]
     * @return: int
     * @description: 十六进制转十进制
     */
    public static int covert(String content) {
        int number = 0;
        String[] HighLetter = {"A", "B", "C", "D", "E", "F"};
        Map<String, Integer> map = new HashMap<>();
        for (int i = 0; i <= 9; i++) {
            map.put(i + "", i);
        }
        for (int j = 10; j < HighLetter.length + 10; j++) {
            map.put(HighLetter[j - 10], j);
        }
        String[] str = new String[content.length()];
        for (int i = 0; i < str.length; i++) {
            str[i] = content.substring(i, i + 1);
        }
        for (int i = 0; i < str.length; i++) {
            number += map.get(str[i]) * Math.pow(16, str.length - 1 - i);
        }
        return number;
    }

    /**
     * 柱状图
     */
    private void initBarChart() {
        barChart = findViewById(R.id.chart2);
        // 背景色
        barChart.setBackgroundColor(Color.WHITE);
        // 图表的文本描述
        barChart.getDescription().setEnabled(false);
        // 手势设置
        barChart.setTouchEnabled(true);
        // 添加监听器
        barChart.setOnChartValueSelectedListener(this);
        barChart.setDrawGridBackground(false);
        // 设置拖拽、缩放等
        barChart.setDragEnabled(true);
        barChart.setScaleEnabled(false);
        barChart.setScaleXEnabled(false);
        barChart.setScaleYEnabled(false);
        barChart.setDrawBarShadow(false);//柱状图没有数据的部分是否显示阴影效果
        barChart.setExtraOffsets(10f, 0f, 10f, 0f);
        barChart.zoom(10f, 0f, 0f, 0f);

        // 获取 X 轴
        XAxis xAxis = barChart.getXAxis();
        xAxis.setAxisMaximum(100);
        // 允许显示 X 轴的垂直网格线
        xAxis.enableGridDashedLine(10f, 0f, 2f);
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        xAxis.setLabelCount(10);

        // 获取 Y 轴
        YAxis yAxis = barChart.getAxisLeft();
        // 禁止右轴
        barChart.getAxisRight().setEnabled(false);
        // Y 轴的水平网格线
        yAxis.enableGridDashedLine(10f, 0f, 2f);
        // 设置 Y 轴的数值范围
        yAxis.setAxisMaximum(300f);
        yAxis.setAxisMinimum(0f);

    }

    private void addBarData(int data) {
        barChart.clear();
        // 1. 每个数据是一个 Entry
        if (values == null) values = new ArrayList<>();
        values.add(new BarEntry(position, data, null));
        // 2. 创建一个数据集 DataSet ，用来添加 Entry。一个图中可以包含多个数据集
        BarDataSet set1 = new BarDataSet(values, "DataSet 1");
//        BarDataSet set2 = new BarDataSet(values, "DataSet 2");
        // 3. 通过数据集设置数据的样式，如字体颜色、线型、线型颜色、填充色、线宽等属性
        // draw dashed line
        set1.setBarBorderColor(Color.TRANSPARENT);
//        set2.setBarBorderColor(Color.TRANSPARENT);
//        set1.setBarBorderWidth(5f);
//        set1.setFormLineWidth(10f);
        // black lines and points
        set1.setColor(data%2 == 0 ? Color.GREEN : Color.BLUE);
//        set2.setColor(Color.BLUE);
        // 4.将数据集添加到数据 ChartData 中
        BarData data1 = new BarData(set1);
        data1.setBarWidth(0.5f);
//        data1.getGroupWidth(10f, 10f);
        // 5. 将数据添加到图表中
        barChart.setData(data1);
        Log.e("LineChart", "XOffset = "+ barChart.getXAxis().getXOffset());
//        barChart.groupBars(0f, 0f, 0f);
//        barChart.invalidate();
        position++;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mHandler != null) {
            mHandler.removeCallbacks(runnable);
        }
    }
}